import records
from quart_cors import cors
from quart import Quart, Blueprint
from quart_auth import AuthManager, Unauthorized
from werkzeug.utils import find_modules, import_string

# 初始化项目
def create_app(config=None):

    # 初始化 Quart
    app = Quart(
        'app',
        static_folder='static',
        template_folder='./view'
    )

    # 权限 登录验证
    AuthManager(app)

    app = cors(app, allow_origin="*")

    # 注册数据库 配置
    config = register_database(app, config)

    # 设置 config配置 项
    app.config.update(config)

    # 静态资源目录
    # app.static('/static', app.config['static'])

    # 注册蓝图
    # 判断是否开启多模块
    if app.config['multi_module'] == False:
        register_blueprints('app.controller', app)
    else:
        # 遍历得到配置里面的模块
        for key, value in app.config['module'].items():
            register_blueprints('app.controller.'+key, app, value)

    # 注册服务 监听器 请求
    # register_server(app)

    @app.errorhandler(Unauthorized)
    async def redirect_login(*_: Exception):
        print('没有登录')
        return {
            'msg': '没有登录',
        }

    return app

# 注册数据库
def register_database(app, config):
    # 连接数据库的参数
    config['db_args'] = dict(
        host=config['database']['host'],
        port=config['database']['port'],
        user=config['database']['user'],
        password=config['database']['pass'],
        database=config['database']['db'],
        charset=config['database']['chartset'],
    )

    if config['database']['type'] == 'sqlite':
        config['db_conn'] = records.Database(config['database']['url'])
    else:
        config['database']['db_url'] = "mysql+pymysql://{user}:{password}@{host}:{port}/{database}?charset={charset}".format(**config['db_args'])
        # records连接  https://github.com/kennethreitz/records
        config['db_conn'] = records.Database(config['db_url'])

    return config

# 注册蓝图
def register_blueprints(root, app, prefix='/'):
    parent = Blueprint("parent"+prefix, __name__, url_prefix=prefix)
    # 遍历模块列表
    for name in find_modules(root, recursive=True):
        mod = import_string(name)
        # 判断是否有 bp
        if hasattr(mod, 'bp'):
            try:
                # 注册路由
                parent.register_blueprint(mod.bp)
                app.register_blueprint(parent)
            except:
                mod.bp.url_prefix = prefix+'/'+mod.bp.name
                app.register_blueprint(mod.bp)
                # print(prefix, mod.bp.name)

# 注册服务
# def register_server(app):
#
#     # 判断是否开启 注册监听器
#     if app.config['listen'] == True:
#         # 注册监听器
#         app.register_listener(listen.before_server_start, 'before_server_start')
#         app.register_listener(listen.before_server_stop, 'before_server_stop')
#         app.register_listener(listen.after_server_start, 'after_server_start')
#         app.register_listener(listen.after_server_stop, 'after_server_stop')
#
#     # 请求
#     @app.on_request
#     async def request(request):
#         http.request(request)
#
#     # 响应
#     @app.on_response
#     async def response(request, response):
#         http.response(request, response)

# async def task():
#     print('Server successfully started!')
